package dongshi.daddy.huohuo;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

// 泛型 T 必须是 Serializable&Comparable&Collection 必须是这三个接口的实现类
public class LambdaDemo<T extends Serializable&Comparable&Collection> {
    
    public static void main(String args[]){
        LambdaDemo demo = new LambdaDemo();

        // Java 8以前的写法，当然现在也可以这样写，只是相对比较麻烦
        MathOperation op2 = new MathOperation<Integer>() {
            @Override
            public Integer operation(int a, int b) {
                return a+b;
            }
        };
        // 参数不写数据类型，直接返回1，生意省略{}和return，相当于MathOperation op1 = (int a, int b) -> { return 1; };
        MathOperation op1 = (a, b) -> 1;
        // 参数声明类型,将两个入参之和作为结果返回，单语句，省略{}和return，相当于MathOperation addition = (int a, int b) -> {return a + b;};
        MathOperation addition = (int a, int b) -> a + b;
        // 参数声明类型,将两个入参之差作为结果返回，单语句，省略{}和return，相当于MathOperation addition = (int a, int b) -> {return a - b;};
        MathOperation subtraction = (int a, int b) -> a - b ;
        // 大括号中的返回语句
        MathOperation multiplication = (int a, int b) -> { 
            //int c = 1000;
            return a * b;// + c;
        };
        // 没有大括号及返回语句
        MathOperation division = (int a, int b) -> a / b;
        
        System.out.println("10 + 5 = " + demo.operate(10, 5, addition));
        System.out.println("10 - 5 = " + demo.operate(10, 5, subtraction));
        System.out.println("10 x 5 = " + demo.operate(10, 5, multiplication));
        System.out.println("10 / 5 = " + demo.operate(10, 5, division));
        System.out.println("10 ^ 5 = " + demo.operate(10, 5, (a, b) -> Math.pow(a,b)));

        // 无参数，只有一个表达式，可以省略{},相当于Runnable task = () -> { System.out.println(1111); };
        Runnable task = () -> System.out.println(1111);
        // 不用括号
        GreetingService greetService1 = message ->
                System.out.println("Hello " + message);
        // 用括号
        GreetingService greetService2 = (message) -> {
            System.out.println(message);
        };
        // 只有一个表达式并且调用的out的方法，可以通过::简写，并且省略参数声明和{},完整写法：GreetingService greetService3 = (message) -> { System.out.println(message); };
//        GreetingService greetService3 = System.out::println;
        GreetingService greetService3 = (String message) -> System.out.println(message);
        // 循环+3输出
        Arrays.asList(1,2,3).forEach(x -> System.out.println(x+3));
        // 循环调用LambdaDemo.println静态方法
        Arrays.asList(1,2,3).forEach( LambdaDemo::println );
        greetService1.sayMessage("kimmking");
        greetService2.sayMessage("Java");
        greetService3.sayMessage("CuiCuilaoshi");

        Collectors.toList();


        BiConsumer<List, Object> biConsumer = (a, b) -> { a.add(b); };
        BiConsumer<List, Object> biConsumer1 = List::add;
    }
    
    private static void println(int x) {
        System.out.println(x+3);
    }

    @FunctionalInterface
    interface MathOperation<T> {
        T operation(int a, int b); // 返回类型+函数名+参数类型的列表
    }
    
    interface GreetingService {
        void sayMessage(String message);
    }
    
    private <T> T operate(int a, int b, MathOperation<T> mathOperation){
        return mathOperation.operation(a, b);
    }
    
}
